package org.papervision3d.materials
{
    import flash.geom.Matrix;
    import flash.display.BitmapData;
    
    import org.papervision3d.core.proto.MaterialObject3D;
    
    // The BitmapMaterial class creates a texture from a BitmapData object.
    // Materials collects data about how objects appear when rendered.
    public class BitmapMaterial extends MaterialObject3D
    {
    	
    	/**
		 * Indicates if mip mapping is forced.
		 */
		static public var AUTO_MIP_MAPPING :Boolean = true;
	
		/**
		 * Levels of mip mapping to force.
		 */
		static public var MIP_MAP_DEPTH :Number = 4;
		
	
        // A texture object.
        public function get texture():*
        {
            return this._texture;
        }
    
        public function set texture(asset:*):void
        {
            this.bitmap   = createBitmap(asset);
            this._texture = asset;
        }
    
        // The BitmapMaterial class creates a texture from a BitmapData object.
        // @param    asset               A BitmapData object.
        // @param    initObject          [optional] - An object that contains additional properties with which to populate the newly created material.
        public function BitmapMaterial(asset:*, initObject:Object = null)
        {
            super(initObject);
    
            texture = asset;
        }
    	
    	public function correctBitmap( bitmap :BitmapData, dispose :Boolean ):BitmapData
		{
			var okBitmap :BitmapData;
	
			var levels :Number = 1 << MIP_MAP_DEPTH;
	
			// Create new bitmap?
			if( AUTO_MIP_MAPPING && bitmap && ( bitmap.width % levels !=0  ||  bitmap.height % levels != 0 ) )
			{
				var width  :Number = levels * Math.ceil( bitmap.width  / levels );
				var height :Number = levels * Math.ceil( bitmap.height / levels );
	
				// Fix to avoid cracks
				var fix:Number = 2;
				this.maxU = (bitmap.width  - fix) / width;
				this.maxV = (bitmap.height - fix) / height;
	
				okBitmap = new BitmapData( width, height, bitmap.transparent, 0x00000000 );
	
				okBitmap.draw( bitmap );
				
				// Dispose bitmap if needed
				if( dispose ) bitmap.dispose();
			}
			else
			{
				this.maxU = this.maxV = 1;
	
				okBitmap = bitmap;
			}
	
			return okBitmap
		}
	
        // Returns a string value representing the material properties in the specified BitmapMaterial object.
        // @return   A string.
        public override function toString():String
        {
            return 'Texture:' + this.texture + ' lineColor:' + this.lineColor + ' lineAlpha:' + this.lineAlpha;
        }
    
        protected function createBitmap(asset:*):BitmapData
        {
           return correctBitmap( asset, true );
        }
        
        override public function dispose() : void {
        	super.dispose();
        	bitmap = null;
        	_texture = null;
        }
    
        protected var _texture:*;
    }
}
